package zmcc.bsp.fabric.config;

import zmcc.bsp.fabric.exception.NetworkBuilderException;
import zmcc.bsp.fabric.network.NetworkGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The root configuration of the fabric and network.
 * 
 * @author ecsoya
 *
 * @see FabricContext
 */
@Component("fabricProperties")
@ConfigurationProperties(prefix = "spring.fabric")
public class FabricProperties {

	/**
	 * The channel name of fabric, required.
	 */
	private String channel;

	/**
	 * The organizations of fabric.
	 */
	private String[] organizations;

	/**
	 * The name of the fabric.
	 */
	private String name;

	/**
	 * The count of all peers.
	 */
	private int peers;

	/**
	 * The gateway configuration of fabric.
	 */
	private FabricGatewayProperties gateway = new FabricGatewayProperties();

	/**
	 * The network configuration of fabric.
	 */
	protected FabricNetworkProperties network = new FabricNetworkProperties();

	/**
	 * The chaincode configuration of fabric.
	 */
	private List<FabricChaincodeProperties> chaincodeList = new ArrayList<>();

	@Autowired
	private NetworkGenerator net;

	/**
	 * @return Load the contents of the network.
	 */
	public InputStream getNetworkContents() {
		if (network == null) {
			return null;
		}
		String file = network.getFile();
		if (file == null || file.equals("")) {
			return null;
		}
		File root = new File("").getAbsoluteFile();

		File localFile = new File(root, file);
		if (!localFile.exists()) {
			InputStream s;
			try {
				s = net.getResourceFromJar(file);
				if (s != null) {
					return s;
				} else {
					net.generateConnectionYmlFile();
					File localFile1 = new File(file);
					try {
						return new FileInputStream(localFile1);
					} catch (FileNotFoundException e) {
						return null;
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}catch (NetworkBuilderException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}
		}
		try {
			return new FileInputStream(localFile);
		} catch (FileNotFoundException e) {
			return null;
		}
	}

	public String getChannel() {
		return channel;
	}

	public void setChannel(String channel) {
		this.channel = channel;
	}

	public String[] getOrganizations() {
		return organizations;
	}

	public void setOrganizations(String[] organizations) {
		this.organizations = organizations;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPeers() {
		return peers;
	}

	public void setPeers(int peers) {
		this.peers = peers;
	}

	public FabricGatewayProperties getGateway() {
		return gateway;
	}

	public void setGateway(FabricGatewayProperties gateway) {
		this.gateway = gateway;
	}

	public FabricNetworkProperties getNetwork() {
		return network;
	}

	public void setNetwork(FabricNetworkProperties network) {
		this.network = network;
	}

	public List<FabricChaincodeProperties> getChaincodeList() {
		return chaincodeList;
	}

	public void setChaincodeList(List<FabricChaincodeProperties> chaincodeList) {
		this.chaincodeList = chaincodeList;
	}

	public NetworkGenerator getNet() {
		return net;
	}

	public void setNet(NetworkGenerator net) {
		this.net = net;
	}
}
